import { userMutations } from '@/utils/mutationName'
import { userActions } from '@/utils/actionName'
import { resetRouter } from '@/router'
import axios from 'axios'

// 解构 mutations 的名称
const {
  SET_UNAME,
  SET_UROLES,
  SET_UROUTES,
  SET_TOKEN,
  SET_FINALUROUTES,
  SET_MENUS
} = userMutations
// 解构 actions 的名称
const {
  LOG_IN,
  GET_USERINFO,
  LOG_OUT,
  GENERATE_FINALROUTES,
  MENUS
} = userActions
export default {
  namespaced: true,
  state: {
    // 用户名
    name: '',
    // 用户的角色列表
    roles: [],
    // 用户的 token
    token: '',
    // 从服务器获取的用户可以访问的路由列表
    uroutes: [],
    // 当前用户最终可以访问的路由列表 (uRoutes + constRoutes)
    finalURoutes: [],
    // 菜单列表
    menus: []
  },
  mutations: {
    // 设置用户名
    [SET_UNAME]: (state, name) => state.name = name,
    // 设置用户的角色列表
    [SET_UROLES]: (state, roles) => state.roles = roles,
    // 设置用户的token
    [SET_TOKEN]: (state, token) => state.token = token,
    // 设置从服务器获取的用户路由表
    [SET_UROUTES]: (state, uroutes) => state.uroutes = uroutes,
    // 设置最终的用户路由列表
    [SET_FINALUROUTES]: (state, routes) => state.finalURoutes = routes,
    [SET_MENUS]: (state, menus) => state.menus = menus
  },
  actions: {
    // 登录
    [LOG_IN]:({ commit }, userInfo) => {
      // 用 promise 进行包装，方便调用方读取结果
      return new Promise((resolve, reject) => {
        // 发送登录请求
        axios({
          url: '/login',
          method: 'post',
          data: userInfo
        }).then(res => {
          const { code, data } = res.data
          if (code !== 200) {
            reject(new Error('request failed!'))
          } else {
            const { token, name } = data
            // 获取用户 token 并存储
            commit(SET_TOKEN, token)
            window.sessionStorage.setItem('token', token)
            // 获取用户名并存储
            commit(SET_UNAME, name)
            window.sessionStorage.setItem('uname', name)
            // 释放钩子函数
            resolve()
          }
        }).catch(err => {
          reject(err)
        })
      })
    },
    // 获取用户信息
    /**
     * 可能需要修改为自己的
     */
    [GET_USERINFO]: ({ commit }, uname) => {
      return new Promise((resolve, reject) => {
        // 发送获取用户信息请求
        axios({
          url: '/getUserInfo',
          method: 'post',
          data: uname
        }).then(res => {
          const { code, data } = res.data
          if (code !== 200) {
            reject(new Error('request failed!'))
          } else {
            const { roles, uroutes } = data.user
            // 构建一个新的路由对象
            const newRoutes = []
            // 将当前用户的菜单列表转换为我们需要的路由列表
            uroutes.forEach(one => {
              // newRoutes的 item 对象
              const item = {}
              // item 对象中的 children
              const childRoutes = []
              if (one.children) {
                one.children.forEach(two => {
                  // 存在子集，考虑 3层
                  if (two.children) {
                    two.children.forEach(three => {
                      childRoutes.push({
                        path: three.path,
                        name: three.component,
                        component: three.component,
                        label: three.label,
                        id: three.id,
                        meta: {
                          hidden: three.hidden
                        }
                      })
                    })
                    item.children = childRoutes
                  } else {
                  // 不存在子集，只考虑 2层
                    childRoutes.push({
                      path: two.path,
                      name: two.component,
                      component: two.component,
                      label: two.label,
                      id: two.id,
                      meta: {
                        hidden: two.hidden
                      }
                    })
                    item.children = childRoutes
                  }
                })
              }
              item.path = one.path
              item.component = one.component
              item.redirect = one.path + '/list'
              item.label = one.label
              item.id = one.id
              item.meta = {
                hidden: one.hidden
              }
              newRoutes.push(item)
            })
            // console.log(newRoutes)
            // 存储角色信息和菜单信息
            commit(SET_UROLES, roles)
            commit(SET_UROUTES, newRoutes)
            // 释放钩子，并将 role 作为参数返回
            resolve(newRoutes)
          }
          // const { data } = res
          // const { role } = data
          // // 解析 permission 字段后重新赋值
          // // 并且当前用户的所有权限信息转换为路由列表
          // const uroutes = []
          // role.forEach(ele => {
          //   let permission = ele.permission
          //   if (permission) {
          //     permission = JSON.parse(permission).permission
          //     permission.forEach(per => {
          //       const category = per.category
          //       const uroute = {}
          //       uroute.path = '/' + category.toLowerCase()
          //       uroute.component = 'layout' // 由于这里都是一级菜单，所以就固定为 layout
          //       uroute.meta = {
          //         title: category
          //       }
          //       uroute.children = [
          //         {
          //           path: '',
          //           component: category,
          //           meta: {
          //             title: category
          //           }
          //         }
          //       ]
          //       if (!uroutes.some(route => uroute.path === route.path)) {
          //         uroutes.push(uroute)
          //       }
          //     })
          //   }
          // })
        }).catch(err => {
          reject(err)
        })
      })
    },
    // 登出
    [LOG_OUT]: ({ commit }) => {
      return new Promise((resolve) => {
        setTimeout(() => {
          // 清空相关全局状态
          commit(SET_TOKEN, '')
          commit(SET_UROLES, [])
          commit(SET_UNAME, '')
          commit(SET_UROUTES, [])
          commit(SET_MENUS, [])
          // 删除本地的 sessionStorage
          window.sessionStorage.removeItem('token')
          window.sessionStorage.removeItem('uname')
          // 重置路由对象
          resetRouter()
          resolve()
        }, 300)
      })
    },
    // 生成最终的用户可以访问的路由列表
    [GENERATE_FINALROUTES]: ({ commit }, constRoutes) => {
      // constRoutes.forEach(item => {
      //   if (item.path === '/') {
      //     item.children.push(...state.uroutes)
      //   }
      // })
      // 将 uroutes 和 constRoutes 进行组合
      commit(SET_FINALUROUTES, constRoutes)
    },
    // 获取菜单
    [MENUS]: ({ commit }, uname) => {
      return new Promise((resolve, reject) => {
        // 发送获取用户信息请求
        axios({
          url: '/getUserInfo',
          method: 'post',
          data: uname
        }).then(res => {
          const { code, data } = res.data
          if (code !== 200) {
            reject(new Error('request failed!'))
          } else {
            const { uroutes } = data.user
            commit(SET_MENUS, uroutes)
            resolve(uroutes)
          }
        }).catch(err => {
          reject(err)
        })
      })
    }
  }
}